

/**
 * Modification of UtilizationTest.java
 * 
 */

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.io.GraphMLFile;

public class DataGenerator 
{

	private ArrayList<Task> tasks;
	private ArrayList<Job> jobs;
	private int lcm;
	private int numberOfCycles;
	
	public DataGenerator(String taskgraphFile) throws IOException
	{
		 // Load the task graph from the graphml file
		this.tasks = parseTaskGraph(taskgraphFile);
		this.lcm = computeLCM();
		this.numberOfCycles = 1 * lcm;
		this.jobs = createJobs();
	
	}
	

	private int computeLCM()
	{
		int tmplcm = 1;
		for(Task task : tasks)
		{
			tmplcm = (task.getPeriod() * tmplcm) / computeGCD(task.getPeriod(), tmplcm);
		}
		return tmplcm;
	}
	
	
	 
//	public static int getLCM(int a, int b)
//	{
//		return (a * b) / getGCD(a, b);
//	}
	
	
	private static int computeGCD(int a, int b)
	{
		int max = Math.max(a, b);
		int min = Math.min(a, b);
		
		if(min == 0)
		{
			return max;
		}
		
		return computeGCD(min, max % min);
	}
	
	private static ArrayList<Task> parseTaskGraph(String filename) throws IOException 
	{
		GraphMLFile gml = new GraphMLFile();
		Graph g = gml.load(filename);

		String name;
		int period;
		int deadline;
		int bcet;
		int wcet;
		
		
		ArrayList<Task> tasks = new ArrayList<Task>();
		for (Iterator<Object> iter = g.getVertices().iterator(); iter.hasNext();) 
		{
			Vertex v = (Vertex) iter.next();

			name = (v.getUserDatum("Name").toString());
			period = (Integer.parseInt((v.getUserDatum("Period")).toString()));
			deadline = (Integer.parseInt((v.getUserDatum("Deadline")).toString()));
			bcet = (Integer.parseInt((v.getUserDatum("BCET")).toString()));
			wcet = (Integer.parseInt((v.getUserDatum("WCET")).toString()));
		 
			Task task = new Task(name,period,deadline,bcet,wcet);
			task.setPriority(Integer.parseInt((v.getUserDatum("Priority")).toString()));
			
			tasks.add(task);
		}
		
		return tasks;
	}
	
	private ArrayList<Job> createJobs()
	{
		ArrayList<Job> jobs = new ArrayList<Job>();
		for(Task task : tasks)
		{
			for(int i = 0; i < numberOfCycles / task.getPeriod(); i++)
			{
				Job job = new Job();
				job.setRelease(task.getPeriod() * i);
				job.setTime((int)(Math.random() * (task.getWcet() - task.getBcet()) * 1.0) + task.getBcet());
				job.setInitTime(job.getTime());
				task.getJobs().add(job);
				job.setOwner(task);
				jobs.add(job);
			}
		}
		
		Collections.sort(jobs, new JobComparator());
		
		return jobs;
	}

	public ArrayList<Task> getTasks() {
		return tasks;
	}
	
	public ArrayList<Job> getAllJobs() {
		return jobs;
	}
	
	public int getLCM() {
		return lcm;
	}
	
	public int getNumberOfCycles() {
		return numberOfCycles;
	}
}
